From a59c39f3703e81f560aa946c25145413192d795b Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Sun, 6 Sep 2009 13:35:37 +0200 Subject: [PATCH] Bug 346800 - Rework sort/filter models to use indices to parents... Rework the sort and filter models to store their reference to the parent element as an array index instead of a pointer to an array element. These pointers could become invalid with any array modification, whereas indices do not. --- gtk/gtktreemodelfilter.c | 156 ++++++++++++++++++++++-------------- gtk/gtktreemodelsort.c | 169 +++++++++++++++++++++++---------------- 2 files changed, 195 insertions(+), 130 deletions(-) diff --git a/gtk/gtktreemodelfilter.c b/gtk/gtktreemodelfilter.c index 1199598e39..214bfe4c5f 100644 --- a/gtk/gtktreemodelfilter.c +++ b/gtk/gtktreemodelfilter.c @@ -73,7 +73,7 @@ struct _FilterLevel gint ref_count; gint visible_nodes; - FilterElt *parent_elt; + gint parent_elt_index; FilterLevel *parent_level; }; @@ -129,6 +129,9 @@ enum #define FILTER_ELT(filter_elt) ((FilterElt *)filter_elt) #define FILTER_LEVEL(filter_level) ((FilterLevel *)filter_level) +#define FILTER_LEVEL_PARENT_ELT(level) (&g_array_index (FILTER_LEVEL ((level))->parent_level->array, FilterElt, FILTER_LEVEL ((level))->parent_elt_index)) +#define FILTER_LEVEL_ELT_INDEX(level, elt) (FILTER_ELT ((elt)) - FILTER_ELT (FILTER_LEVEL ((level))->array->data)) + /* general code (object/interface init, properties, etc) */ static void gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface); static void gtk_tree_model_filter_drag_source_init (GtkTreeDragSourceIface *iface); @@ -214,7 +217,7 @@ static gboolean gtk_tree_model_filter_drag_data_delete (GtkTr /* private functions */ static void gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, FilterLevel *parent_level, - FilterElt *parent_elt, + gint parent_elt_index, gboolean emit_inserted); static void gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter, @@ -438,12 +441,13 @@ gtk_tree_model_filter_get_property (GObject *object, static void gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, FilterLevel *parent_level, - FilterElt *parent_elt, + gint parent_elt_index, gboolean emit_inserted) { GtkTreeIter iter; GtkTreeIter first_node; GtkTreeIter root; + FilterElt *parent_elt = NULL; FilterLevel *new_level; gint length = 0; gint i; @@ -476,6 +480,8 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, GtkTreeIter parent_iter; GtkTreeIter child_parent_iter; + parent_elt = &g_array_index (parent_level->array, FilterElt, parent_elt_index); + parent_iter.stamp = filter->priv->stamp; parent_iter.user_data = parent_level; parent_iter.user_data2 = parent_elt; @@ -501,10 +507,10 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, length); new_level->ref_count = 0; new_level->visible_nodes = 0; - new_level->parent_elt = parent_elt; + new_level->parent_elt_index = parent_elt_index; new_level->parent_level = parent_level; - if (parent_elt) + if (parent_elt_index >= 0) parent_elt->children = new_level; else filter->priv->root = new_level; @@ -512,9 +518,9 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, /* increase the count of zero ref_counts */ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } if (new_level != filter->priv->root) @@ -628,13 +634,13 @@ gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter, if (filter_level->ref_count == 0) { FilterLevel *parent_level = filter_level->parent_level; - FilterElt *parent_elt = filter_level->parent_elt; + gint parent_elt_index = filter_level->parent_elt_index; while (parent_level) { - parent_elt->zero_ref_count--; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -642,8 +648,8 @@ gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter, filter->priv->zero_ref_count--; } - if (filter_level->parent_elt) - filter_level->parent_elt->children = NULL; + if (filter_level->parent_elt_index >= 0) + FILTER_LEVEL_PARENT_ELT (filter_level)->children = NULL; else filter->priv->root = NULL; @@ -674,7 +680,10 @@ gtk_tree_model_filter_elt_get_path (FilterLevel *level, { gtk_tree_path_prepend_index (path, walker2->offset); - walker2 = walker->parent_elt; + if (!walker->parent_level) + break; + + walker2 = FILTER_LEVEL_PARENT_ELT (walker); walker = walker->parent_level; } @@ -810,18 +819,21 @@ static gboolean gtk_tree_model_filter_elt_is_visible_in_target (FilterLevel *level, FilterElt *elt) { + gint elt_index; + if (!elt->visible) return FALSE; - if (!level->parent_elt) + if (level->parent_elt_index == -1) return TRUE; do { - elt = level->parent_elt; + elt_index = level->parent_elt_index; level = level->parent_level; - if (elt && !elt->visible) + if (elt_index >= 0 + && !g_array_index (level->array, FilterElt, elt_index).visible) return FALSE; } while (level); @@ -873,11 +885,11 @@ gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter, FilterElt elt; /* check if child exists and is visible */ - if (level->parent_elt) + if (level->parent_elt_index >= 0) { c_parent_path = gtk_tree_model_filter_elt_get_path (level->parent_level, - level->parent_elt, + FILTER_LEVEL_PARENT_ELT (level), filter->priv->virtual_root); if (!c_parent_path) return NULL; @@ -956,7 +968,7 @@ gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter, { FilterElt *e = &(g_array_index (level->array, FilterElt, i)); if (e->children) - e->children->parent_elt = e; + e->children->parent_elt_index = i; } c_iter.stamp = filter->priv->stamp; @@ -975,14 +987,18 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, { FilterElt *elt, *parent; FilterLevel *level, *parent_level; - gint i, length; + gint i, length, parent_elt_index; gboolean emit_child_toggled = FALSE; level = FILTER_LEVEL (iter->user_data); elt = FILTER_ELT (iter->user_data2); - parent = level->parent_elt; + parent_elt_index = level->parent_elt_index; + if (parent_elt_index >= 0) + parent = FILTER_LEVEL_PARENT_ELT (level); + else + parent = NULL; parent_level = level->parent_level; length = level->array->len; @@ -999,8 +1015,8 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, if (level != filter->priv->root && level->visible_nodes == 0 - && level->parent_elt - && level->parent_elt->visible) + && parent + && parent->visible) emit_child_toggled = TRUE; if (length > 1) @@ -1047,7 +1063,7 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, */ elt = &g_array_index (level->array, FilterElt, i); if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } } } @@ -1294,7 +1310,7 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model, { FilterLevel *root; - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); root = FILTER_LEVEL (filter->priv->root); } @@ -1432,7 +1448,7 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model, goto done; /* build level will pull in the new child */ - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); if (filter->priv->root && FILTER_LEVEL (filter->priv->root)->visible_nodes) @@ -1559,7 +1575,7 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model, { FilterElt *e = &g_array_index (level->array, FilterElt, i); if (e->children) - e->children->parent_elt = e; + e->children->parent_elt_index = i; } /* don't emit the signal if we aren't visible */ @@ -1618,7 +1634,7 @@ gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model, if (filter->priv->virtual_root && !filter->priv->root && !gtk_tree_path_compare (c_path, filter->priv->virtual_root)) { - gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE); + gtk_tree_model_filter_build_level (filter, NULL, -1, TRUE); return; } @@ -1686,7 +1702,9 @@ gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model, * can monitor it for changes. */ if (elt->ref_count > 1 && gtk_tree_model_iter_has_child (c_model, c_iter)) - gtk_tree_model_filter_build_level (filter, level, elt, TRUE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + TRUE); /* get a path taking only visible nodes into account */ path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter); @@ -1844,7 +1862,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, if (elt->offset > offset) elt->offset--; if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } return; @@ -1869,7 +1887,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, { emit_child_toggled = TRUE; parent_level = level->parent_level; - parent = level->parent_elt; + parent = FILTER_LEVEL_PARENT_ELT (level); } /* emit row_deleted */ @@ -1914,7 +1932,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, if (elt->offset > offset) elt->offset--; if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } } @@ -2108,7 +2126,7 @@ gtk_tree_model_filter_rows_reordered (GtkTreeModel *c_model, { FilterElt *e = &g_array_index (level->array, FilterElt, i); if (e->children) - e->children->parent_elt = e; + e->children->parent_elt_index = i; } /* emit rows_reordered */ @@ -2209,7 +2227,7 @@ gtk_tree_model_filter_get_iter_full (GtkTreeModel *model, indices = gtk_tree_path_get_indices (path); if (filter->priv->root == NULL) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); depth = gtk_tree_path_get_depth (path); @@ -2229,7 +2247,9 @@ gtk_tree_model_filter_get_iter_full (GtkTreeModel *model, elt = gtk_tree_model_filter_get_nth (filter, level, indices[i]); if (!elt->children) - gtk_tree_model_filter_build_level (filter, level, elt, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + FALSE); level = elt->children; } @@ -2264,7 +2284,7 @@ gtk_tree_model_filter_get_iter (GtkTreeModel *model, indices = gtk_tree_path_get_indices (path); if (filter->priv->root == NULL) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); depth = gtk_tree_path_get_depth (path); @@ -2284,7 +2304,9 @@ gtk_tree_model_filter_get_iter (GtkTreeModel *model, elt = gtk_tree_model_filter_get_nth_visible (filter, level, indices[i]); if (!elt->children) - gtk_tree_model_filter_build_level (filter, level, elt, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + FALSE); level = elt->children; } @@ -2311,6 +2333,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, GtkTreePath *retval; FilterLevel *level; FilterElt *elt; + gint elt_index; g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), NULL); g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, NULL); @@ -2318,6 +2341,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, level = iter->user_data; elt = iter->user_data2; + elt_index = FILTER_LEVEL_ELT_INDEX (level, elt); if (!elt->visible) return NULL; @@ -2328,7 +2352,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, { int i = 0, index = 0; - while (&g_array_index (level->array, FilterElt, i) != elt) + while (i < elt_index) { if (g_array_index (level->array, FilterElt, i).visible) index++; @@ -2338,7 +2362,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, } gtk_tree_path_prepend_index (retval, index); - elt = level->parent_elt; + elt_index = level->parent_elt_index; level = level->parent_level; } @@ -2431,7 +2455,7 @@ gtk_tree_model_filter_iter_children (GtkTreeModel *model, int i = 0; if (!filter->priv->root) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); if (!filter->priv->root) return FALSE; @@ -2461,20 +2485,24 @@ gtk_tree_model_filter_iter_children (GtkTreeModel *model, else { int i = 0; + FilterElt *elt; + + elt = FILTER_ELT (parent->user_data2); - if (FILTER_ELT (parent->user_data2)->children == NULL) + if (elt->children == NULL) gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (parent->user_data), - FILTER_ELT (parent->user_data2), + FILTER_LEVEL_ELT_INDEX (parent->user_data, elt), FALSE); - if (FILTER_ELT (parent->user_data2)->children == NULL) + + if (elt->children == NULL) return FALSE; - if (FILTER_ELT (parent->user_data2)->children->visible_nodes <= 0) + if (elt->children->visible_nodes <= 0) return FALSE; iter->stamp = filter->priv->stamp; - iter->user_data = FILTER_ELT (parent->user_data2)->children; + iter->user_data = elt->children; level = FILTER_LEVEL (iter->user_data); @@ -2524,7 +2552,8 @@ gtk_tree_model_filter_iter_has_child (GtkTreeModel *model, if (!elt->children && gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter)) gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data), - elt, FALSE); + FILTER_LEVEL_ELT_INDEX (iter->user_data, elt), + FALSE); if (elt->children && elt->children->visible_nodes > 0) return TRUE; @@ -2548,7 +2577,7 @@ gtk_tree_model_filter_iter_n_children (GtkTreeModel *model, if (!iter) { if (!filter->priv->root) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); if (filter->priv->root) return FILTER_LEVEL (filter->priv->root)->visible_nodes; @@ -2567,7 +2596,8 @@ gtk_tree_model_filter_iter_n_children (GtkTreeModel *model, gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter)) gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data), - elt, FALSE); + FILTER_LEVEL_ELT_INDEX (iter->user_data, elt), + FALSE); if (elt->children) return elt->children->visible_nodes; @@ -2633,7 +2663,7 @@ gtk_tree_model_filter_iter_parent (GtkTreeModel *model, { iter->stamp = GTK_TREE_MODEL_FILTER (model)->priv->stamp; iter->user_data = level->parent_level; - iter->user_data2 = level->parent_elt; + iter->user_data2 = FILTER_LEVEL_PARENT_ELT (level); return TRUE; } @@ -2666,14 +2696,14 @@ gtk_tree_model_filter_ref_node (GtkTreeModel *model, if (level->ref_count == 1) { FilterLevel *parent_level = level->parent_level; - FilterElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; /* we were at zero -- time to decrease the zero_ref_count val */ while (parent_level) { - parent_elt->zero_ref_count--; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -2719,14 +2749,14 @@ gtk_tree_model_filter_real_unref_node (GtkTreeModel *model, if (level->ref_count == 0) { FilterLevel *parent_level = level->parent_level; - FilterElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; /* we are at zero -- time to increase the zero_ref_count val */ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -3221,7 +3251,7 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte child_indices = gtk_tree_path_get_indices (real_path); if (filter->priv->root == NULL && build_levels) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); for (i = 0; i < gtk_tree_path_get_depth (real_path); i++) @@ -3241,7 +3271,9 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte { gtk_tree_path_append_index (retval, j); if (!tmp->children && build_levels) - gtk_tree_model_filter_build_level (filter, level, tmp, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, tmp), + FALSE); level = tmp->children; found_child = TRUE; } @@ -3263,7 +3295,9 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte gtk_tree_path_append_index (retval, j); if (!tmp->children && build_levels) - gtk_tree_model_filter_build_level (filter, level, tmp, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, tmp), + FALSE); level = tmp->children; found_child = TRUE; } @@ -3355,7 +3389,7 @@ gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *filter, retval = gtk_tree_path_new (); filter_indices = gtk_tree_path_get_indices (filter_path); if (!filter->priv->root) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); for (i = 0; i < gtk_tree_path_get_depth (filter_path); i++) @@ -3372,7 +3406,9 @@ gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *filter, filter_indices[i]); if (elt->children == NULL) - gtk_tree_model_filter_build_level (filter, level, elt, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + FALSE); if (!level || level->visible_nodes <= filter_indices[i]) { diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c index 4525bca8b1..f07795cc23 100644 --- a/gtk/gtktreemodelsort.c +++ b/gtk/gtktreemodelsort.c @@ -67,7 +67,7 @@ struct _SortLevel { GArray *array; gint ref_count; - SortElt *parent_elt; + gint parent_elt_index; SortLevel *parent_level; }; @@ -101,6 +101,10 @@ enum { #define SORT_ELT(sort_elt) ((SortElt *)sort_elt) #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level) +#define SORT_LEVEL_PARENT_ELT(level) (&g_array_index (SORT_LEVEL ((level))->parent_level->array, SortElt, SORT_LEVEL ((level))->parent_elt_index)) +#define SORT_LEVEL_ELT_INDEX(level, elt) (SORT_ELT ((elt)) - SORT_ELT (SORT_LEVEL ((level))->array->data)) + + #define GET_CHILD_ITER(tree_model_sort,ch_iter,so_iter) gtk_tree_model_sort_convert_iter_to_child_iter((GtkTreeModelSort*)(tree_model_sort), (ch_iter), (so_iter)); #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1) @@ -211,7 +215,7 @@ static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable /* Private functions (sort funcs, level handling and other utils) */ static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, SortLevel *parent_level, - SortElt *parent_elt); + gint parent_elt_index); static void gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort, SortLevel *sort_level); static void gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort); @@ -499,7 +503,7 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model, for (i = 0; i < level->array->len; i++) if (g_array_index (level->array, SortElt, i).children) - g_array_index (level->array, SortElt, i).children->parent_elt = &g_array_index (level->array, SortElt, i); + g_array_index (level->array, SortElt, i).children->parent_elt_index = i; gtk_tree_path_up (path); gtk_tree_path_append_index (path, index); @@ -539,11 +543,11 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model, /* else? shouldn't really happen */ } - if (level->parent_elt) + if (level->parent_elt_index >= 0) { iter.stamp = tree_model_sort->stamp; iter.user_data = level->parent_level; - iter.user_data2 = level->parent_elt; + iter.user_data2 = SORT_LEVEL_PARENT_ELT (level); tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter); @@ -609,7 +613,7 @@ gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model, if (!tree_model_sort->root) { - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); /* the build level already put the inserted iter in the level, so no need to handle this signal anymore */ @@ -785,7 +789,7 @@ gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model, if (elt->offset > offset) elt->offset--; if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } gtk_tree_path_free (path); @@ -934,7 +938,7 @@ gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model, indices = gtk_tree_path_get_indices (path); if (tree_model_sort->root == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); level = SORT_LEVEL (tree_model_sort->root); depth = gtk_tree_path_get_depth (path); @@ -948,7 +952,7 @@ gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model, return FALSE; if (g_array_index (level->array, SortElt, indices[i]).children == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, indices[i])); + gtk_tree_model_sort_build_level (tree_model_sort, level, indices[i]); level = g_array_index (level->array, SortElt, indices[i]).children; } @@ -972,19 +976,21 @@ gtk_tree_model_sort_get_path (GtkTreeModel *tree_model, GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; GtkTreePath *retval; SortLevel *level; - SortElt *elt; + gint elt_index; g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL); g_return_val_if_fail (tree_model_sort->stamp == iter->stamp, NULL); retval = gtk_tree_path_new (); - level = iter->user_data; - elt = iter->user_data2; - while (level != NULL) + + level = SORT_LEVEL (iter->user_data); + elt_index = SORT_LEVEL_ELT_INDEX (level, iter->user_data2); + + while (level) { - gtk_tree_path_prepend_index (retval, elt - (SortElt *)level->array->data); + gtk_tree_path_prepend_index (retval, elt_index); - elt = level->parent_elt; + elt_index = level->parent_elt_index; level = level->parent_level; } @@ -1048,7 +1054,7 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model, if (parent == NULL) { if (tree_model_sort->root == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); if (tree_model_sort->root == NULL) return FALSE; @@ -1059,15 +1065,21 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model, } else { - if (((SortElt *)parent->user_data2)->children == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, - (SortLevel *)parent->user_data, - (SortElt *)parent->user_data2); - if (((SortElt *)parent->user_data2)->children == NULL) + SortElt *elt; + + level = SORT_LEVEL (parent->user_data); + elt = SORT_ELT (parent->user_data2); + + if (elt->children == NULL) + gtk_tree_model_sort_build_level (tree_model_sort, level, + SORT_LEVEL_ELT_INDEX (level, elt)); + + if (elt->children == NULL) return FALSE; + iter->stamp = tree_model_sort->stamp; - iter->user_data = ((SortElt *)parent->user_data2)->children; - iter->user_data2 = ((SortLevel *)iter->user_data)->array->data; + iter->user_data = elt->children; + iter->user_data2 = elt->children->array->data; } return TRUE; @@ -1160,7 +1172,7 @@ gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model, { iter->stamp = tree_model_sort->stamp; iter->user_data = level->parent_level; - iter->user_data2 = level->parent_elt; + iter->user_data2 = SORT_LEVEL_PARENT_ELT (level); return TRUE; } @@ -1173,9 +1185,9 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model, { GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; GtkTreeIter child_iter; - GtkTreeIter tmp_iter; - SortLevel *level; + SortLevel *level, *parent_level; SortElt *elt; + gint parent_elt_index; g_return_if_fail (tree_model_sort->child_model != NULL); g_return_if_fail (VALID_ITER (iter, tree_model_sort)); @@ -1193,28 +1205,34 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model, level->ref_count++; /* Increase the reference count of all parent elements */ - tmp_iter.stamp = tree_model_sort->stamp; - tmp_iter.user_data = level->parent_level; - tmp_iter.user_data2 = level->parent_elt;; + parent_level = level->parent_level; + parent_elt_index = level->parent_elt_index; - while (tmp_iter.user_data2) + while (parent_level) { + GtkTreeIter tmp_iter; + + tmp_iter.stamp = tree_model_sort->stamp; + tmp_iter.user_data = parent_level; + tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index); + gtk_tree_model_sort_ref_node (tree_model, &tmp_iter); - tmp_iter.user_data2 = SORT_LEVEL (tmp_iter.user_data)->parent_elt; - tmp_iter.user_data = SORT_LEVEL (tmp_iter.user_data)->parent_level; + parent_elt_index = parent_level->parent_elt_index; + parent_level = parent_level->parent_level; } if (level->ref_count == 1) { SortLevel *parent_level = level->parent_level; - SortElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; + /* We were at zero -- time to decrement the zero_ref_count val */ while (parent_level) - { - parent_elt->zero_ref_count--; + { + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -1229,9 +1247,9 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model, gboolean propagate_unref) { GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; - GtkTreeIter tmp_iter; - SortLevel *level; + SortLevel *level, *parent_level; SortElt *elt; + gint parent_elt_index; g_return_if_fail (tree_model_sort->child_model != NULL); g_return_if_fail (VALID_ITER (iter, tree_model_sort)); @@ -1253,29 +1271,34 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model, level->ref_count--; /* Decrease the reference count of all parent elements */ - tmp_iter.stamp = tree_model_sort->stamp; - tmp_iter.user_data = level->parent_level; - tmp_iter.user_data2 = level->parent_elt;; + parent_level = level->parent_level; + parent_elt_index = level->parent_elt_index; - while (tmp_iter.user_data2) + while (parent_level) { + GtkTreeIter tmp_iter; + + tmp_iter.stamp = tree_model_sort->stamp; + tmp_iter.user_data = parent_level; + tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index); + gtk_tree_model_sort_real_unref_node (tree_model, &tmp_iter, FALSE); - tmp_iter.user_data2 = SORT_LEVEL (tmp_iter.user_data)->parent_elt; - tmp_iter.user_data = SORT_LEVEL (tmp_iter.user_data)->parent_level; + parent_elt_index = parent_level->parent_elt_index; + parent_level = parent_level->parent_level; } if (level->ref_count == 0) { SortLevel *parent_level = level->parent_level; - SortElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; /* We are at zero -- time to increment the zero_ref_count val */ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -1558,10 +1581,10 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort, /* Set up data */ data.tree_model_sort = tree_model_sort; - if (level->parent_elt) + if (level->parent_elt_index >= 0) { data.parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level, - level->parent_elt); + SORT_LEVEL_PARENT_ELT (level)); gtk_tree_path_append_index (data.parent_path, 0); } else @@ -1627,9 +1650,8 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort, new_order[i] = g_array_index (sort_array, SortTuple, i).offset; g_array_append_val (new_array, *elt); - elt = &g_array_index (new_array, SortElt, i); if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } g_array_free (level->array, TRUE); @@ -1639,11 +1661,11 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort, if (emit_reordered) { gtk_tree_model_sort_increment_stamp (tree_model_sort); - if (level->parent_elt) + if (level->parent_elt_index >= 0) { iter.stamp = tree_model_sort->stamp; iter.user_data = level->parent_level; - iter.user_data2 = level->parent_elt; + iter.user_data2 = SORT_LEVEL_PARENT_ELT (level); path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter); @@ -1846,7 +1868,7 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort, tmp_elt = SORT_ELT (level->array->data); for (i = 0; i < level->array->len; i++, tmp_elt++) if (tmp_elt->children) - tmp_elt->children->parent_elt = tmp_elt; + tmp_elt->children->parent_elt_index = i; return TRUE; } @@ -1869,7 +1891,10 @@ gtk_tree_model_sort_elt_get_path (SortLevel *level, { gtk_tree_path_prepend_index (path, walker2->offset); - walker2 = walker->parent_elt; + if (!walker->parent_level) + break; + + walker2 = SORT_LEVEL_PARENT_ELT (walker); walker = walker->parent_level; } @@ -1992,7 +2017,7 @@ gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_mode child_indices = gtk_tree_path_get_indices (child_path); if (tree_model_sort->root == NULL && build_levels) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); level = SORT_LEVEL (tree_model_sort->root); for (i = 0; i < gtk_tree_path_get_depth (child_path); i++) @@ -2018,7 +2043,7 @@ gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_mode gtk_tree_path_append_index (retval, j); if (g_array_index (level->array, SortElt, j).children == NULL && build_levels) { - gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, j)); + gtk_tree_model_sort_build_level (tree_model_sort, level, j); } level = g_array_index (level->array, SortElt, j).children; found_child = TRUE; @@ -2136,7 +2161,7 @@ gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sor retval = gtk_tree_path_new (); sorted_indices = gtk_tree_path_get_indices (sorted_path); if (tree_model_sort->root == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); level = SORT_LEVEL (tree_model_sort->root); for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++) @@ -2151,7 +2176,7 @@ gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sor } if (g_array_index (level->array, SortElt, count).children == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, count)); + gtk_tree_model_sort_build_level (tree_model_sort, level, count); if (level == NULL) { @@ -2203,9 +2228,10 @@ gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sor static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, SortLevel *parent_level, - SortElt *parent_elt) + gint parent_elt_index) { GtkTreeIter iter; + SortElt *parent_elt = NULL; SortLevel *new_level; gint length = 0; gint i; @@ -2223,6 +2249,8 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, GtkTreeIter parent_iter; GtkTreeIter child_parent_iter; + parent_elt = &g_array_index (parent_level->array, SortElt, parent_elt_index); + parent_iter.stamp = tree_model_sort->stamp; parent_iter.user_data = parent_level; parent_iter.user_data2 = parent_elt; @@ -2248,10 +2276,10 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, new_level = g_new (SortLevel, 1); new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length); new_level->ref_count = 0; - new_level->parent_elt = parent_elt; new_level->parent_level = parent_level; + new_level->parent_elt_index = parent_elt_index; - if (parent_elt) + if (parent_elt_index >= 0) parent_elt->children = new_level; else tree_model_sort->root = new_level; @@ -2259,11 +2287,12 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, /* increase the count of zero ref_counts.*/ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } + if (new_level != tree_model_sort->root) tree_model_sort->zero_ref_count++; @@ -2334,13 +2363,13 @@ gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort, if (sort_level->ref_count == 0) { SortLevel *parent_level = sort_level->parent_level; - SortElt *parent_elt = sort_level->parent_elt; + gint parent_elt_index = sort_level->parent_elt_index; while (parent_level) - { - parent_elt->zero_ref_count--; + { + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -2348,8 +2377,8 @@ gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort, tree_model_sort->zero_ref_count--; } - if (sort_level->parent_elt) - sort_level->parent_elt->children = NULL; + if (sort_level->parent_elt_index >= 0) + SORT_LEVEL_PARENT_ELT (sort_level)->children = NULL; else tree_model_sort->root = NULL; -- 2.30.2